package com.example.springDemo.config;

import ch.qos.logback.classic.db.DBHelper;
import com.example.springDemo.bean.Car;
import com.example.springDemo.bean.Person;
import com.example.springDemo.bean.Pet;
import com.example.springDemo.bean.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportResource;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 1.配置类里面使用@Bean标注在方法上给容器注册组件，
 *      默认也是单实例(创建一次 即 即使在new 也是同一个)的
 * 2.配置类本身也是组件
 * 3.@Configuratio()   proxyBeanMethods:是不是代理bean的方法(代理说明得这个类操作 单实例的)
 *       Full(proxyBeanMethods = true)//单实例   默认  每次都先判断有没有创建过组件
 *       Lite(proxyBeanMethods = false)//多实例
 *
 * 最佳实战
 *     配置类组件之间无依赖关系用Lite模式加速容器启动过程,减少判断
 *     配置类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式
 *
 * 4.@Import({User.class})
 *      给容器中自动创建出这个类型的组件   默认组建的名称就是"全类名"
 *
 *
 */
@Import({User.class, DBHelper.class})//给容器中自动创建出这个类型的组件
@Configuration//(proxyBeanMethods = false)//这是一个配置类 == 配置文件告诉spring boot这是一个配置类 主要
@ImportResource("classpath:beans.xml")//将beans.xml里的组件导入
@EnableConfigurationProperties({Car.class,Person.class})//
//1.开启Car的配置绑定功能//2.把这个Car的个组件自动注册到容器中
public class MyConfig {

    /**
     @ConditionalOnClass()//存在()内这个类才加载
     @ConditionalOnMissingClass()//不存在存在()内这个类才加载
     */
//    @ConditionalOnMissingBean(name = "tom")//当没有tom这个组件才加载这个组件
    @ConditionalOnBean(name = "pet01")//当有pet01这个组件时  才加载这个组件
    //（如果pet01在后面 仍然不加载）   因为在准备加载这个组件时   pet01组件没有加载
    @Bean//给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值，就是组件在容器中的实例
    public User user01(){
        /*
         * @Configuration(proxyBeanMethods = true)
         *   说明都是"单实例"的   说明了user01组件依赖于pet01组件
         *
         * @Configuration(proxyBeanMethods = false)
         *
         * */
        User user = new User("张三", 18);
        user.setPet(pet01());
        return user;
    }

    @Bean("pet01")//默认组件名字为方法名   也可以自定义组件名字("pet01")
    public Pet pet01(){
        return new Pet("小狗",15.5);
    }

}
